package com.douyang.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.douyang.base.myAnnotation.OrderStatementLog;
import com.douyang.base.enumeration.OrderStatementStatusEnum;
import com.douyang.base.enumeration.PayOrderStatusEnum;
import com.douyang.base.expcetion.TradeException;
import com.douyang.base.model.UserBaseInfo;
import com.douyang.base.utils.IdWorkerUtils;
import com.douyang.base.utils.UserUtil;
import com.douyang.model.OrderStatement;
import com.douyang.mapper.OrderStatementMapper;
import com.douyang.model.PayOrderBase;
import com.douyang.model.PayOrderDetail;
import com.douyang.service.OrderStatementLogService;
import com.douyang.service.OrderStatementService;
import com.douyang.service.PayOrderBaseService;
import com.douyang.service.PayOrderDetailService;
import com.douyang.util.AlipayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xiaoma
 * @since 2025-04-22
 */
@Service
public class OrderStatementServiceImpl extends ServiceImpl<OrderStatementMapper, OrderStatement> implements OrderStatementService {

    @Autowired
    private PayOrderBaseService payOrderBaseService;

    @Autowired
    private PayOrderDetailService payOrderDetailService;

    @Autowired
    private AlipayUtil alipayUtil;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    @Lazy
    private OrderStatementService self;

    @Autowired
    @Lazy
    OrderStatementLogService orderStatementLogService;

    @Override
    @OrderStatementLog
    public Long createOrderStatement(Long orderId) {
        //检查订单状态
        if(orderId == null){throw new TradeException("参数异常");}
        UserBaseInfo loginUserBaseInfo = UserUtil.getLoginUserBaseInfo();

        boolean exists = payOrderBaseService.lambdaQuery()
                .eq(PayOrderBase::getOrderId, orderId)
                .eq(PayOrderBase::getUserId, loginUserBaseInfo.getId())
                .exists();

        if (!exists) {throw new TradeException("订单不存在");}

        PayOrderDetail payOrderDetail = payOrderDetailService.lambdaQuery().eq(PayOrderDetail::getOrderId, orderId).one();
        if(!Objects.equals(payOrderDetail.getOrderStatus(), PayOrderStatusEnum.CREATE))throw new TradeException("订单状态异常");


        //创建订单交易流水

        OrderStatement orderStatement = OrderStatement.builder()
                .id(IdWorkerUtils.getInstance().nextId())
                .createTime(LocalDateTime.now())
                .orderId(orderId)
                .orderTitle(payOrderDetail.getOrderTitle())
                .status(OrderStatementStatusEnum.CREATED)
                .userId(loginUserBaseInfo.getId())
                .price(payOrderDetail.getPrice())
                .userName(loginUserBaseInfo.getUserName())
                .build();
        save(orderStatement);

        return orderStatement.getId();
    }

    @Override
    public String tryToPay(Long orderStatementId) {
        UserBaseInfo userBaseInfo = UserUtil.getLoginUserBaseInfo();
        OrderStatement orderStatement = lambdaQuery()
                .eq(OrderStatement::getId, orderStatementId)
                .eq(OrderStatement::getUserId, userBaseInfo.getId())
                .one();

        PayOrderDetail payOrderDetail = payOrderDetailService.lambdaQuery().eq(PayOrderDetail::getOrderId, orderStatement.getOrderId()).one();
        if(!PayOrderStatusEnum.CREATE.equals(payOrderDetail.getOrderStatus()))throw new TradeException("订单状态异常，可能已支付。");

        try {
            return alipayUtil.sendToAlipay(orderStatement.getId().toString(),orderStatement.getPrice().toString(),orderStatement.getOrderTitle());
        }catch (Exception e){
            throw new TradeException(e.getMessage());
        }

    }

    @Override
    @OrderStatementLog
    public String payNotify(Map<String, String> param) {
        try {
            Boolean check = alipayUtil.check(param);
            if(check){
                self.updateDb(param);
                return "success";
            }else{
                throw new RuntimeException();
            }
        }catch (Exception e){
            stringRedisTemplate.delete("payNotifyVis："+param.get("trade_no"));
            return "failure";
        }
    }

    public void updateDb(Map<String, String> param) {
        Boolean b = stringRedisTemplate.opsForValue().setIfAbsent("payNotifyVis："+param.get("trade_no"), param.get("trade_no"), 1, TimeUnit.DAYS);
        if(Boolean.FALSE.equals(b))return;

        if("TRADE_SUCCESS".equals(param.get("trade_status"))){
            OrderStatement orderStatement = getById(param.get("out_trade_no"));
            if(orderStatement == null){return;}
            boolean update = payOrderDetailService
                    .lambdaUpdate()
                    .eq(PayOrderDetail::getOrderId, orderStatement.getOrderId())
                    .eq(PayOrderDetail::getOrderStatus, PayOrderStatusEnum.CREATE)
                    .set(PayOrderDetail::getOrderStatus, PayOrderStatusEnum.PAYED)
                    .set(PayOrderDetail::getUpdateTime,LocalDateTime.now())
                    .update();
            if(!update){
                //订单状态异常 退款
                self.updateOrderStatementState(orderStatement,OrderStatementStatusEnum.REFUNDING,"该订单状态异常，可能已被支付",null);
                try {
                    Double price = alipayUtil.alipayTradeRefund(orderStatement.getId().toString(), "该订单状态异常，可能已被支付",orderStatement.getPrice().toString());
                    if(price==null){
                        self.updateOrderStatementState(orderStatement,OrderStatementStatusEnum.UNKNOWN,"退款未知--支付宝回调异常",null);
                    }else{
                        self.updateOrderStatementState(orderStatement,OrderStatementStatusEnum.REFUND,null,price);
                    }
                }catch (Exception e){
                    self.updateOrderStatementState(orderStatement,OrderStatementStatusEnum.FAIL,"退款失败--支付宝服务器异常",null);
                }
            }else{
                lambdaUpdate()
                        .eq(OrderStatement::getId, param.get("out_trade_no"))
                        .set(OrderStatement::getStatus, OrderStatementStatusEnum.PAYED)
                        .set(OrderStatement::getPayTime,LocalDateTime.now())
                        .update();
                saveOrderStatementLog(orderStatement.getId(),orderStatement.getOrderId());
            }

        }
    }

    private void saveOrderStatementLog(Long orderStatementId,Long orderId) {
        com.douyang.model.OrderStatementLog orderStatementLog=new com.douyang.model.OrderStatementLog();
        orderStatementLog.setOrderStatementId(orderStatementId);
        orderStatementLog.setCreateTime(LocalDateTime.now());
        orderStatementLog.setResult("修改成功");
        orderStatementLog.setOps("尝试修改订单("+orderId.toString()+")状态为支付成功");
        orderStatementLog.setSuccess(true);
        orderStatementLogService.save(orderStatementLog);
    }

    @OrderStatementLog
    public void updateOrderStatementState(OrderStatement orderStatement, int state, String failReason,Double price) {
        orderStatement.setStatus(state);
        if(StringUtils.isNotEmpty(failReason))orderStatement.setFailReason(failReason);
        if(price!=null)orderStatement.setPrice(price);
        updateById(orderStatement);
    }
}
